/*
 * An interface for FIFO
 * FIFO is a container of data, in this FIFO, data is represented by "char*"
 */

#ifndef CM_FIFO_H
#define CM_FIFO_H

#ifdef __cplusplus
extern "C" {
#endif

/* struct cm_fifo contains the details of a FIFO's implementation */
typedef struct cm_fifo cmfifo_t;

enum CMFIFO_OP {
    CMFIFO_GET, CMFIFO_PUT
};

/*
 * @brief   在进行了读或写操作以后，设置FIFO内部的状态
 * @param   op: 指示是进行了读还是写操作，
 *          若操作为读(CMFIFO_GET)则内部可用空间增大(数据被读走)
 *          若操作为写(CMFIFO_PUT)则内部空间被占用一块(数据被写入)
 * @param   size: 一共操作了多少数据
 * @return  0 成功， -1 失败
 */
int cmfifo_setstatus(cmfifo_t *fifo, enum CMFIFO_OP op, unsigned size);

/*
 * @return  队列为空则返回1 否则返回0
 */
int cmfifo_empty(struct cm_fifo *fifo);

/*
 * @brief   返回队列中有多少可读的数据
 */
unsigned cmfifo_readable(struct cm_fifo *fifo);

/*
 * @brief   返回队列中还有多少空间可以用来存放数据
 */
unsigned cmfifo_space(struct cm_fifo *fifo);

/*
 * @brief   返回队列的大小，大小在创建队列时指定
 */
unsigned cmfifo_size(cmfifo_t *fifo);

/*
 * @brief	清空数据
 */
void cmfifo_reset(cmfifo_t *pfifo);

/*
 * @brief   直接获取FIFO中的数据指针，因为存储的内部形式，所以完整的数据需要两个指针来表示
 * @param   通过ptr1和size1返回第一个指针所指向的数据和数据大小, 通过ptr2和size2返回第二部分数据和大小
 *      如果该部分没有数据则返回NULL和0, 第一部分没有数据则第二部分一定没有数据
 * @return  0表示成功， -1表示失败
 */
int cmfifo_dataptr(cmfifo_t *fifo, char **ptr1, unsigned *size1, char **ptr2,
        unsigned *size2);

/*
 * @brief   直接获取FIFO中可以用来存放数据的空间的指针，因为存储的内部形式，所以完整的空间需要两个指针来表示
 * @param   通过ptr1和size1返回第一个指针所指向的空间和空间大小, 通过ptr2和size2返回第二部分空间和大小
 *      如果该部分没有空间则返回NULL和0, 第一个指针为NULL则第二个一定为NULL
 * @return  0表示成功， -1表示失败
 */
int cmfifo_spaceptr(cmfifo_t *fifo, char **ptr1, unsigned *size1, char **ptr2,
        unsigned *size2);

/*
 * @brief	create a FIFO and set it's size to 's'
 * @return	A pointer to the new FIFO or NULL for failed.
 */
cmfifo_t *cmfifo_create(unsigned s);

void cmfifo_destroy(cmfifo_t **pfifo);

/*
 * @brief	put some data into a FIFO.
 * @return	if there is enough space for putting, then save the data and return 0 for success,
 * 		return -1 for error
 */
int cmfifo_putdata(cmfifo_t *pfifo, const char *src, unsigned s);

/*
 * @brief	get 'size' bytes of data from a FIFO, and copy it into data
 * @brief	return 0 for success, -1 for error (not enough data for getting or other errors)
 */
int cmfifo_getdata(cmfifo_t *pfifo, char *dest, unsigned s);

int cmfifo_tryget(cmfifo_t *pfifo, char *dest, unsigned s);


#ifdef __cplusplus
}
#endif

#endif

